package connect5.ia;

import java.util.Vector;
import java.lang.Math;
import connect5.Grille;

public class ValidGrille {
	
	private static int nombreGagnant = 5;
	private static boolean compteExact = true;
	private static int lastValue = 0;
	private static int count = 0;
	private static int quiGagne = 0;
	private static boolean playerIsWhite;
	private static char[] DATA_TYPE = {'0', 'N', 'B'};
    private static boolean DEBUG_MODE_ACTIVATED = true;
    private static int STICKING_VALUE = 25;
	
	private static boolean aGagner;
	private static boolean aPerdu;
	
	private static int multiplierFactor = 10;
	
	private static int maxValue = Integer.MAX_VALUE;
	private static int minValue = Integer.MIN_VALUE; 
	
	private static int totalEvaluation;
	
	public static int determineGagnant(Grille grille) { 
        quiGagne = lastValue = 0; // reset status

        // horizontal
        for (int l = 0; l < grille.getData().length; l++) {
            for (int c = 0; c < grille.getData()[0].length; c++) {
                check(grille.getData()[l][c]);
            }
            check(0);
        }

        // vertical
        for (int c = 0; c < grille.getData()[0].length; c++) {
            for (int l = 0; l < grille.getData().length; l++) {
                check(grille.getData()[l][c]);
            }
            check(0);
        }

        // Diagonal \\\\\\\
        for (int c = -grille.getData().length; c < grille.getData()[0].length; c++) {
            int c2 = c;
            int l = 0;
            if (c2 < 0) {
                l = -c2;
                c2 = 0;
            }
            for (; c2 < grille.getData()[0].length && l < grille.getData().length; c2++, l++) {
                check(grille.getData()[l][c2]);
            }
            check(0);
        }

        // Diagonal //////
        for (int c = -grille.getData().length; c < grille.getData()[0].length; c++) {
            int c2 = c;
            int l = grille.getData().length - 1;
            if (c2 < 0) {
                l += c2;
                c2 = 0;
            }
            for (; c2 < grille.getData()[0].length && l >= 0; c2++, l--) {
                check(grille.getData()[l][c2]);
            }
            check(0);
        }

        return quiGagne;
    }
	
	private static void check(int value) {
        if (value == lastValue) {
            count++;
        } else {
            if (lastValue > 0 && (compteExact ? count == nombreGagnant : count >= nombreGagnant)) {
                quiGagne = lastValue;
            }
            count = 1;
            lastValue = value;
        }
    }
	
	@SuppressWarnings("unchecked")
	public static int determineValeurGrille(Grille grille, int[] position, byte currentPlayer) {
		aGagner = false;
		aPerdu = false;
		playerIsWhite = currentPlayer == JoueurArtificiel.VALUE_B;
		// Initalisation des variables
		totalEvaluation = 0;
		int value = 0;
		
		//DEBUG_LN("Determination d'une valeur de grille pour la grille : ");
		//DEBUG_LN(grille.toString());
		
		Vector<Byte> vecteur = new Vector<Byte>();
		// horizontal
        for (int l = 0; l < grille.getData().length; l++) {
            
            count = 0;
    		lastValue = 0;
    		vecteur.clear();
        	
        	for (int c = 0; c < grille.getData()[0].length; c++) {
        		vecteur.add(grille.getData()[l][c]);
            }
        	Vector<Byte> vecteurClone = null;
            if(DEBUG_MODE_ACTIVATED){
            	vecteurClone = (Vector<Byte>) vecteur.clone();
            }
        	value = checkValue(vecteur);
        	if (value>0 && DEBUG_MODE_ACTIVATED){
	        	DEBUG("For line : ");
	        	for(Byte data : vecteurClone){
	        		DEBUG(DATA_TYPE[data] + "");
	        	}
	
	        	DEBUG_LN(" Value is " + value + " Gagner : " + aGagner + " Perdu : " + aPerdu);
	        	
        	}
        	totalEvaluation += value;
        	
        	if (aGagner){
        		return maxValue;
        	}
        	
        	if (aPerdu){
        		return minValue;
        	}
        }

        // vertical
        for (int c = 0; c < grille.getData()[0].length; c++) {
            
            count = 0;
    		lastValue = 0;
    		vecteur.clear();
        	
        	for (int l = 0; l < grille.getData().length; l++) {
        		vecteur.add(grille.getData()[l][c]);
            }
        	Vector<Byte> vecteurClone = null;
            if(DEBUG_MODE_ACTIVATED){
            	vecteurClone = (Vector<Byte>) vecteur.clone();
            }
        	value = checkValue(vecteur);
        	if (value>0 && DEBUG_MODE_ACTIVATED){
	        	DEBUG("For Column : ");
	        	for(Byte data : vecteurClone){
	        		DEBUG(DATA_TYPE[data]  +"");
	        	}
	        	
	        	DEBUG_LN(" Value is " + value + " Gagner : " + aGagner + " Perdu : " + aPerdu);
        	}
        	totalEvaluation += value;
        	if (aGagner){
        		return maxValue;
        	}
        	
        	if (aPerdu){
        		return minValue;
        	}
        }

        // Diagonal \\\\\\\
        for (int c = -grille.getData().length; c < grille.getData()[0].length; c++) {
            
            count = 0;
    		lastValue = 0;
        	
        	int c2 = c;
            int l = 0;
            if (c2 < 0) {
                l = -c2;
                c2 = 0;
            }
    		vecteur.clear();
            for (; c2 < grille.getData()[0].length && l < grille.getData().length; c2++, l++) {
	            vecteur.add(grille.getData()[l][c2]);
	        }
            Vector<Byte> vecteurClone = null;
            if(DEBUG_MODE_ACTIVATED){
            	vecteurClone = (Vector<Byte>) vecteur.clone();
            }
            value = checkValue(vecteur);
            if(value != 0 && DEBUG_MODE_ACTIVATED){
	            DEBUG("For Diagonal \\ : ");
	        	for(Byte data : vecteurClone){
	        		DEBUG(DATA_TYPE[data]  +"");
	        	}
	        	DEBUG_LN(" Value is " + value + " Gagner : " + aGagner + " Perdu : " + aPerdu);
            }
            totalEvaluation += value;
	    	
	    	if (aGagner){
        		return maxValue;
        	}
        	
        	if (aPerdu){
        		return minValue;
        	}
        }

        // Diagonal //////
        for (int c = -grille.getData().length; c < grille.getData()[0].length; c++) {
            
            count = 0;
    		lastValue = 0;
        	
        	int c2 = c;
            int l = grille.getData().length - 1;
            if (c2 < 0) {
                l += c2;
                c2 = 0;
            }
    		vecteur.clear();
            for (; c2 < grille.getData()[0].length && l >= 0; c2++, l--) {
            	vecteur.add(grille.getData()[l][c2]);
            }
            Vector<Byte> vecteurClone = null;
            if(DEBUG_MODE_ACTIVATED){
            	vecteurClone = (Vector<Byte>) vecteur.clone();
            }
            value = checkValue(vecteur);
            if(value>0 && DEBUG_MODE_ACTIVATED){
	            DEBUG("For Diagonal / : ");
	        	for(Byte data : vecteurClone){
	        		DEBUG(DATA_TYPE[data] +"");
	        	}
	        	DEBUG_LN(" Value is " + value + " Gagner : " + aGagner + " Perdu : " + aPerdu);
            }
            totalEvaluation += value;
        	
        	if (aGagner){
        		return maxValue;
        	}
        	
        	if (aPerdu){
        		return minValue;
        	}
        }

		 return totalEvaluation;
	}

	private static int checkValue(Vector<Byte> vecteur) {
		if (vecteur.size()>=5){
			switch (vecteur.remove(0)){
			case JoueurArtificiel.VALUE_B:
				return XB(1, vecteur);
				
			case JoueurArtificiel.VALUE_N: 
				return XN(1, vecteur);
				
			default : // z�ro JoueurArticiel.VALUE_0
				return X0(1, vecteur);
			}
		}
		
		return 0;
    }
	
	private static int X0(int X, Vector<Byte> vecteur){
		
		if(vecteur.size() != 0){
			switch (vecteur.remove(0)){
			case JoueurArtificiel.VALUE_B:
				return X0YB(X, 1,vecteur);
				
			case JoueurArtificiel.VALUE_N:
				return X0YN(X, 1,vecteur);
	
			default : // z�ro JoueurArticiel.VALUE_0
				return X0(++X, vecteur);
			}
		}
		else{
			return 0;
		}
	
	}
	private static int XB(int X, Vector<Byte> vecteur){
		if(vecteur.size() != 0){
			switch (vecteur.remove(0)){
			case JoueurArtificiel.VALUE_B:
				return XB(++X, vecteur);
				
			case JoueurArtificiel.VALUE_N:
				if(X == 5){
					if(playerIsWhite)
						aGagner = true;
					else
						aPerdu = true;
					return 0;
				}
				// if player is white et X == 1
				return countPoints(STICKING_VALUE, JoueurArtificiel.VALUE_B) + XN(1, vecteur);
				
			default : // z�ro JoueurArticiel.VALUE_0
				if (X == 5){
					if(playerIsWhite)
						aGagner = true;
					else
						aPerdu = true;
					return 0;
				}
				return XBY0(X, 1, vecteur);
			}
		}
		else{
			if (X == 5){
				if(playerIsWhite){
					aGagner = true;
					return 0;
				}
				else
					aPerdu = true;
			}
			return 0;
		}
	}
	
	
	private static int XN(int X, Vector<Byte> vecteur){
		if(vecteur.size() != 0){
			switch (vecteur.remove(0)){
			case JoueurArtificiel.VALUE_B:
				if(X == 5){
					if(!playerIsWhite)
						aGagner = true;
					else
						aPerdu = true;
					return 0;
				}
				return countPoints(STICKING_VALUE, JoueurArtificiel.VALUE_N) + XB(1, vecteur);
				
			case JoueurArtificiel.VALUE_N:
				return XN(++X, vecteur);
				
			default : // z�ro JoueurArticiel.VALUE_0
				if (X == 5){
					if(!playerIsWhite)
						aGagner = true;
					else
						aPerdu = true;
					return 0;
				}
				return XNY0(X, 1, vecteur);
			}
		}
		else{
			if (X == 5){
				if(!playerIsWhite)
					aGagner = true;
				else
					aPerdu = true;
			}
			return 0;
		}
	}
	private static int XBY0(int X, int Y, Vector<Byte> vecteur){
		if(vecteur.size() != 0){
			switch (vecteur.remove(0)){
			case JoueurArtificiel.VALUE_B:
				if(X+Y > 5){	
					if(Y>1){
						if(X > 5){
							return X0YB(Y-1,1,vecteur);
						}
						//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
						return countPoints((int)java.lang.Math.pow(multiplierFactor, X), JoueurArtificiel.VALUE_B) + X0YB(Y-1,1,vecteur);
					}
					return XB(1, vecteur);
				}
				else if(X+Y == 5){
					return XB(1,vecteur);
				}
				return XBY0ZB(X,Y,1,vecteur);
			case JoueurArtificiel.VALUE_N:
				if(X+Y < 5 || X > 5){
					return X0YN(Y, 1,vecteur);
				}
				else{
					//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
					return countPoints((int)java.lang.Math.pow(multiplierFactor, X), JoueurArtificiel.VALUE_B) + X0YN(Y, 1,vecteur);
				}
			default : // z�ro JoueurArticiel.VALUE_0
				return XBY0(X, ++Y, vecteur);
			}
		}
		else{
			if(X+Y < 5 || X > 5){
				return 0;
			}
			else{
				//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
				return countPoints((int)java.lang.Math.pow(multiplierFactor, X), JoueurArtificiel.VALUE_B);
			}
		}
	}
	private static int XNY0(int X, int Y, Vector<Byte> vecteur){
		if(vecteur.size() != 0){
			switch (vecteur.remove(0)){
			case JoueurArtificiel.VALUE_N:
				if(X+Y > 5)
				{
					if(Y>1){
						if(X > 5)
						{
							return X0YN(Y-1,1,vecteur);
						}
						//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
						return countPoints((int)java.lang.Math.pow(multiplierFactor, X), JoueurArtificiel.VALUE_N) + X0YN(Y-1,1,vecteur);
					}
					return XN(1, vecteur);
				}
				else if(X+Y == 5){
					return XN(1,vecteur);
				}
				return XNY0ZN(X,Y,1,vecteur);
			case JoueurArtificiel.VALUE_B:
				if(X+Y < 5 || X > 5)
					return X0YB(Y, 1,vecteur);
				else{
					//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
					return countPoints((int)java.lang.Math.pow(multiplierFactor, X), JoueurArtificiel.VALUE_N) + X0YB(Y, 1,vecteur);
				}
				
			default : // z�ro JoueurArticiel.VALUE_0
				return XNY0(X, ++Y, vecteur);
			}
		}
		else{
			if(X+Y < 5 || X > 5)
				return 0;
			else{
				//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
				return countPoints((int)java.lang.Math.pow(multiplierFactor, X), JoueurArtificiel.VALUE_N);
			}
		}
	}

	private static int X0YB(int X, int Y, Vector<Byte> vecteur){
		if(vecteur.size() != 0){
			switch (vecteur.remove(0)){
			case JoueurArtificiel.VALUE_B:
				return X0YB(X, ++Y, vecteur);
				
			case JoueurArtificiel.VALUE_N:
				if (Y == 5){
					if(playerIsWhite)
						aGagner = true;
					else
						aPerdu = true;
					return 0;
				}
				else if(X+Y >= 5 && Y < 5){
					//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
					if(Y==1 && playerIsWhite)
						return countPoints(STICKING_VALUE, JoueurArtificiel.VALUE_B) + countPoints((int)java.lang.Math.pow(multiplierFactor, Y), JoueurArtificiel.VALUE_B) + XN( 1, vecteur);
					else if (!playerIsWhite && isAlone(vecteur))
						return countPoints(STICKING_VALUE, JoueurArtificiel.VALUE_N) + countPoints((int)java.lang.Math.pow(multiplierFactor, Y), JoueurArtificiel.VALUE_B) + XN( 1, vecteur);
					else
						return countPoints((int)java.lang.Math.pow(multiplierFactor, Y), JoueurArtificiel.VALUE_B) + XN( 1, vecteur);
				}
				if(Y==1 && playerIsWhite)
					return countPoints(STICKING_VALUE, JoueurArtificiel.VALUE_B) + XN( 1, vecteur);
				else
					return XN( 1, vecteur);
				
			default : // z�ro JoueurArticiel.VALUE_0
				if ( Y == 5){
					if(playerIsWhite)
						aGagner = true;
					else
						aPerdu = true;
					return 0;
				}
				else if (Y > 5)
					return XBY0(Y,1,vecteur);
				return X0YBZ0(X, Y, 1, vecteur);
			}
		}
		else{
			if (Y == 5){
				if(playerIsWhite)
					aGagner = true;
				else
					aPerdu = true;
			}
			else if(X+Y >= 5 && Y < 5){
				//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
				return countPoints((int)java.lang.Math.pow(multiplierFactor, Y), JoueurArtificiel.VALUE_B);
			}
			return 0;
		}
	}
	
	private static int X0YN(int X, int Y, Vector<Byte> vecteur){
		if(vecteur.size() != 0){
			switch (vecteur.remove(0)){
			case JoueurArtificiel.VALUE_B:
				if( Y == 5){
					if(!playerIsWhite)
						aGagner = true;
					else
						aPerdu = true;
					return 0;
				}
				else if(X+Y >= 5 && Y < 5){
					//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
					if(Y==1 && !playerIsWhite)
						return countPoints(STICKING_VALUE, JoueurArtificiel.VALUE_N) + countPoints((int)java.lang.Math.pow(multiplierFactor, Y), JoueurArtificiel.VALUE_N) + XB( 1, vecteur);
					else if (playerIsWhite && isAlone(vecteur))
						return countPoints(STICKING_VALUE, JoueurArtificiel.VALUE_B) + countPoints((int)java.lang.Math.pow(multiplierFactor, Y), JoueurArtificiel.VALUE_N) + XB( 1, vecteur);
					else
						return countPoints((int)java.lang.Math.pow(multiplierFactor, Y), JoueurArtificiel.VALUE_N) + XB( 1, vecteur);
				}
				if(Y==1 && !playerIsWhite)
					return countPoints(STICKING_VALUE, JoueurArtificiel.VALUE_N) + XB( 1, vecteur);
				else
					return XB( 1, vecteur);
			case JoueurArtificiel.VALUE_N:
				return X0YN(X, ++Y, vecteur);
				
			default : // z�ro JoueurArticiel.VALUE_0
				if ( Y == 5){
					if(!playerIsWhite)
						aGagner = true;
					else
						aPerdu = true;
					return 0;
				}
				else if (Y > 5)
					return XNY0(Y,1,vecteur);
				return X0YNZ0(X,Y,1,vecteur);
			}
		}
		else{
			if( Y == 5)
			{
				if(!playerIsWhite)
					aGagner = true;
				else
					aPerdu = true;
			}
			else if(X+Y >= 5 && Y < 5){
				//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
				return countPoints((int)java.lang.Math.pow(multiplierFactor, Y), JoueurArtificiel.VALUE_N);
			}
			return 0;
		}
	}

	private static int XBY0ZB(int X, int Y, int Z, Vector<Byte> vecteur){
		if(vecteur.size() != 0){
			switch (vecteur.remove(0)){
			case JoueurArtificiel.VALUE_B:
				return XBY0ZB(X,Y,++Z, vecteur);
			case JoueurArtificiel.VALUE_N:
				if(Z == 5){
					if(playerIsWhite)
						aGagner = true;
					else
						aPerdu = true;
					return 0;
				}
				else if (Z > 5){
					return XN(1, vecteur);
				}
				else{
					int point = 0;
					if(X+Y+Z == 5){
						//////////////////////////////////////////////////////////////////////////////////////////////////////////
						point = countPoints((int)java.lang.Math.pow(multiplierFactor, X+Z) - (int)(java.lang.Math.pow(multiplierFactor, X+Z)*Y/4), JoueurArtificiel.VALUE_B);
					}
					else if(Y+Z > 5){
						//////////////////////////////////////////////////////////////////////////////////////////////////////////
						point = countPoints((int)java.lang.Math.pow(multiplierFactor, Z), JoueurArtificiel.VALUE_B);
					}
					else if(Y==1 && playerIsWhite){
						point = countPoints(STICKING_VALUE, JoueurArtificiel.VALUE_B);
					}
					else if(!playerIsWhite && isAlone(vecteur)){
						point = countPoints(STICKING_VALUE, JoueurArtificiel.VALUE_N);
					}
					return point + XN(1, vecteur);
				}
			default : 
				if(Z == 5){
					if(playerIsWhite)
						aGagner = true;
					else
						aPerdu = true;
					return 0;
				}
				else if(X+Y+Z == 5){
					/////////////////////////////////////////////////////////////////////
					return countPoints((int)java.lang.Math.pow(multiplierFactor, X+Z)- (int)(java.lang.Math.pow(multiplierFactor, X+Z)*Y/4), JoueurArtificiel.VALUE_B) + X0YBZ0(Y,Z,1,vecteur);
				}
				else if(X+Y+Z < 5){
					return XBY0ZBQ0(X, Y, Z,1,vecteur); 
				}
				else if(Y > 1){
					return X0YBZ0(Y-1,Z,1,vecteur);
				}
				else {
					return XBY0(Z,1,vecteur);
				}
			}
		}
		else{
			if(Z == 5){
				if(playerIsWhite)
					aGagner = true;
				else
					aPerdu = true;
				return 0;
			}
			else if (Z > 5){
				return 0;
			}
			else{
				int point = 0;
				if(X+Y+Z == 5){
					//////////////////////////////////////////////////////////////////////////////////////////////////////////
					point = countPoints((int)java.lang.Math.pow(multiplierFactor, X+Z)- (int)(java.lang.Math.pow(multiplierFactor, X+Z)*Y/4), JoueurArtificiel.VALUE_B);
				}
				else if(X+Y+Z > 5 &&  Y+Z > 5){
					//////////////////////////////////////////////////////////////////////////////////////////////////////////
					point = countPoints((int)java.lang.Math.pow(multiplierFactor, Z), JoueurArtificiel.VALUE_B);
				}
				return point;
			}
		}
	}
	
	private static int XNY0ZN(int X, int Y, int Z, Vector<Byte> vecteur){
		if(vecteur.size() != 0){
			switch (vecteur.remove(0)){
			case JoueurArtificiel.VALUE_N:
				return XNY0ZN(X,Y,++Z, vecteur);
			case JoueurArtificiel.VALUE_B:
				if(Z == 5){ 
					if(!playerIsWhite)
						aGagner = true;
					else
						aPerdu = true;
					return 0;
				}
				else if (Z > 5){
					return countPoints(STICKING_VALUE, JoueurArtificiel.VALUE_N) + XB(1, vecteur);
				}
				else{
					int point = 0;
					if(X+Y+Z == 5){
						//////////////////////////////////////////////////////////////////////////////////////////////////////////
						point = countPoints((int)java.lang.Math.pow(multiplierFactor, X+Z)- (int)(java.lang.Math.pow(multiplierFactor, X+Z)*Y/4), JoueurArtificiel.VALUE_N);
					}
					else if(X+Y+Z > 5 &&  Y+Z > 5){
						//////////////////////////////////////////////////////////////////////////////////////////////////////////
						point = countPoints((int)java.lang.Math.pow(multiplierFactor, Z), JoueurArtificiel.VALUE_N);
					}
					else if(Y==1 && !playerIsWhite){
						point = countPoints(STICKING_VALUE, JoueurArtificiel.VALUE_N) + XB( 1, vecteur);
					}
					else if(playerIsWhite && isAlone(vecteur)){
						point = countPoints(STICKING_VALUE, JoueurArtificiel.VALUE_B);
					}
				return point + XB(1, vecteur);
				}
			default : 
				if(Z == 5){
					if(!playerIsWhite)
						aGagner = true;
					else
						aPerdu = true;
					return 0;
				}
				else if(X+Y+Z == 5){
					/////////////////////////////////////////////////////////////////////
					return countPoints((int)java.lang.Math.pow(multiplierFactor, X+Z)- (int)(java.lang.Math.pow(multiplierFactor, X+Z)*Y/4), JoueurArtificiel.VALUE_N) + X0YNZ0(Y,Z,1,vecteur);
				}
				else if(X+Y+Z < 5){
					return XNY0ZNQ0(X, Y, Z,1,vecteur); 
				}
				else if(Y > 1){
					return X0YNZ0(Y-1,Z,1,vecteur);
				}
				else {
					return XNY0(Z,1,vecteur);
				}
			}
		}
		else {
			if(Z == 5){ 
				if(!playerIsWhite)
					aGagner = true;
				else
					aPerdu = true;
				return 0;
			}
			else if (Z > 5){
				return 0;
			}
			else{
				int point = 0;
				if(X+Y+Z == 5){
					//////////////////////////////////////////////////////////////////////////////////////////////////////////
					point = countPoints((int)java.lang.Math.pow(multiplierFactor, X+Z)- (int)(java.lang.Math.pow(multiplierFactor, X+Z)*Y/4), JoueurArtificiel.VALUE_N);
				}
				else if(Y+Z > 5){
					//////////////////////////////////////////////////////////////////////////////////////////////////////////
					point = countPoints((int)java.lang.Math.pow(multiplierFactor, Z), JoueurArtificiel.VALUE_N);
				}
				return point;
			}
		}
	}

	private static int X0YBZ0(int X, int Y, int Z, Vector<Byte> vecteur){
		if(vecteur.size() != 0){
			switch (vecteur.remove(0)){
			case JoueurArtificiel.VALUE_B:
				if(X >= 1 && Y >= 3 && Y < 5){
					return countPoints((int) (java.lang.Math.pow(multiplierFactor, Y+1)*0.9), JoueurArtificiel.VALUE_B) + XB(1, vecteur);
				}
				else if((Y+Z)>=5 || (X+Y)>=5){ 
					if(Z != 1){
						/////////////////////////////////////////////////////////////////////////////////////
						return countPoints((int)java.lang.Math.pow(multiplierFactor, Y), JoueurArtificiel.VALUE_B) + X0YB(Z-1, 1, vecteur);
					}
					else{
						/////////////////////////////////////////////////////////////////////////////////////
						return countPoints((int)java.lang.Math.pow(multiplierFactor, Y), JoueurArtificiel.VALUE_B) + XB(1, vecteur);
					}
				}
				return X0YBZ0QB(X, Y, Z, 1, vecteur);
				
			case JoueurArtificiel.VALUE_N:
				if(X >= 1 && Y >= 3 && Y < 5){
					return countPoints((int)(java.lang.Math.pow(multiplierFactor, Y+1)*0.9), JoueurArtificiel.VALUE_B) + XN(1, vecteur);
				}
				else if ((X+Y+Z)>=5){
					////////////////////////////////////////////////////////////////////////////////
					return countPoints((int)java.lang.Math.pow(multiplierFactor, Y), JoueurArtificiel.VALUE_B) + X0YN(Z, 1, vecteur);
				}
				return X0YN(Z, 1, vecteur);
				
			default : // z�ro JoueurArticiel.VALUE_0
				return X0YBZ0(X, Y, ++Z, vecteur);
			}
		}
		else
		{
			if(X >= 1 && Y >= 3 && Y < 5){
				return countPoints((int)(java.lang.Math.pow(multiplierFactor, Y+1)*0.9), JoueurArtificiel.VALUE_B);
			}
			if ((X+Y+Z)>=5){
				//////////////////////////////////////////////////////////////////////
				return countPoints((int)java.lang.Math.pow(multiplierFactor, Y), JoueurArtificiel.VALUE_B);
			}
			return 0;
		}
	}
	
	private static int X0YNZ0(int X, int Y, int Z, Vector<Byte> vecteur){
		if(vecteur.size() != 0){
			switch (vecteur.remove(0)){
			case JoueurArtificiel.VALUE_N:
				if(X >= 1 && Y >= 3 && Y < 5){
					return countPoints((int)(java.lang.Math.pow(multiplierFactor, Y+1)*0.9), JoueurArtificiel.VALUE_N) + XN(1, vecteur);
				}
				else if((Y+Z)>=5 || (X+Y)>=5){ 
					if(Z != 1){
						///////////////////////////////////////////
						return countPoints((int)java.lang.Math.pow(multiplierFactor, Y) + X0YN(Z-1, 1, vecteur), JoueurArtificiel.VALUE_N);
					}
					else{
						/////////////////////////
						return countPoints((int)java.lang.Math.pow(multiplierFactor, Y) + XN(1, vecteur), JoueurArtificiel.VALUE_N);
					}
				}
				return X0YNZ0QN(X, Y, Z, 1, vecteur);
				
			case JoueurArtificiel.VALUE_B:
				if(X >= 1 && Y >= 3 && Y < 5){
					return countPoints((int)(java.lang.Math.pow(multiplierFactor, Y+1)*0.9), JoueurArtificiel.VALUE_N) + XB(1, vecteur);
				}
				if ((X+Y+Z)>=5){
					return countPoints((int)java.lang.Math.pow(multiplierFactor, Y), JoueurArtificiel.VALUE_N) + X0YB(Z, 1, vecteur);
				}
				return X0YB(Z, 1, vecteur);
				
			default : // z�ro JoueurArticiel.VALUE_0
				return X0YNZ0(X, Y, ++Z, vecteur);
			}
		}
		else{
			if(X >= 1 && Y >= 3 && Y < 5){
				return countPoints((int)(java.lang.Math.pow(multiplierFactor, Y+1)*0.9), JoueurArtificiel.VALUE_N);
			}
			if ((X+Y+Z)>=5){
				return countPoints((int)java.lang.Math.pow(multiplierFactor, Y), JoueurArtificiel.VALUE_N);
			}
			return 0;
		}
	}
	
	private static int X0YNZ0QN(int X, int Y, int Z, int Q, Vector<Byte> vecteur) {
		if(vecteur.size() != 0){
			switch (vecteur.remove(0)){
			case JoueurArtificiel.VALUE_B:
				int pointN = 0;
				if(Q == 5){
					if(!playerIsWhite)
						aGagner = true;
					else
						aPerdu = true;
					return 0;
				}
				else if (Q > 5){
					pointN += 0;
				}
				else if ((Q + Z) > 5){
					// Donne les point pour 0QNB 
					///////////////////////////////////////////////////////////////////
					pointN += countPoints((int)java.lang.Math.pow(multiplierFactor, Q), JoueurArtificiel.VALUE_N);
				}
				else if((Q + Z + Y) == 5 ){
					// Donne les point pour YNZ0QN
					pointN += countPoints((int)java.lang.Math.pow(multiplierFactor, Y+Q) - (int)(java.lang.Math.pow(multiplierFactor, Y+Q)*Z/4), JoueurArtificiel.VALUE_N); // Rajouter facteur espacement Z
				}
				else if((Q + Z + Y) < 5 && (Q + Z + Y + X) >= 5 ){
					// Donne les point pour X0YNZ0QN
					/////////////////////////////////////////////////////////////////
					pointN += countPoints((int)java.lang.Math.pow(multiplierFactor, Y+Q) - (int)(java.lang.Math.pow(multiplierFactor, Y+Q)*Z/4), JoueurArtificiel.VALUE_N); // Rajouter facteur espacement Z
				}
				else if((Y == 1 && Z == 1 && Q == 2) ||(Y == 2 && Z == 1 && Q ==1)){
					pointN += countPoints((int)(java.lang.Math.pow(multiplierFactor, Y+Q+1)*0.9), JoueurArtificiel.VALUE_N);
				}
				else if(Q==1 && !playerIsWhite){
					pointN += countPoints(STICKING_VALUE, JoueurArtificiel.VALUE_N);
				}
				else if(playerIsWhite && isAlone(vecteur)){
					pointN = countPoints(STICKING_VALUE, JoueurArtificiel.VALUE_B);
				}
				return pointN + XB(1, vecteur);
				
			case JoueurArtificiel.VALUE_N:
				return X0YNZ0QN(X, Y, Z, ++Q, vecteur);
				
			default : // z�ro JoueurArticiel.VALUE_0
				if(Q == 5){
					if(!playerIsWhite)
						aGagner = true;
					else
						aPerdu = true;
					return 0;
				}
				else if((Y == 1 && Z == 1 && Q == 2) ||(Y == 2 && Z == 1 && Q ==1)){
					return countPoints((int)(java.lang.Math.pow(multiplierFactor, Y+Q+1)*0.9), JoueurArtificiel.VALUE_N) + X0YNZ0(Z,Q,1,vecteur);
				}
				else if (Q > 5){
					return XNY0(Q, 1, vecteur);
				}
				else if ((Q + Z) >= 5){
					// Donne les point pour 0QNB 
					///////////////////////////////////////////////////////////////////
					return X0YNZ0(Z, Q, 1, vecteur) ;
				}
				else if((Q + Z + Y) == 5 ){
					// Donne les point pour YNZ0QN
					////////////////////
					if ( Z != 1)
						return countPoints((int)java.lang.Math.pow(multiplierFactor, Y+Q) - (int)(java.lang.Math.pow(multiplierFactor, Y+Q)*Z/4), JoueurArtificiel.VALUE_N) + X0YNZ0(Z-1, Q, 1, vecteur); // Rajouter facteur espacement Z
					else
						return countPoints((int)java.lang.Math.pow(multiplierFactor, Y+Q) - (int)(java.lang.Math.pow(multiplierFactor, Y+Q)*Z/4), JoueurArtificiel.VALUE_N) + XNY0(Q, 1, vecteur); // Rajouter facteur espacement Z
				}
				else if((Q + Z + Y) < 5 && (Q + Z + Y + X) >= 4 ){ // ERREUR VOLONTAIRE
					// Donne les point pour X0YNZ0QN
					/////////////////////////////////////////////////////////////////
					if ( Z != 1)
						return countPoints((int)java.lang.Math.pow(multiplierFactor, Y+Q) - (int)(java.lang.Math.pow(multiplierFactor, Y+Q)*Z/4), JoueurArtificiel.VALUE_N) + X0YNZ0(Z-1, Q, 1, vecteur); // Rajouter facteur espacement Z
					else
						return countPoints((int)java.lang.Math.pow(multiplierFactor, Y+Q) - (int)(java.lang.Math.pow(multiplierFactor, Y+Q)*Z/4), JoueurArtificiel.VALUE_N) + XNY0(Q, 1, vecteur);
				}
				return XNY0(Q, 1, vecteur);
			}
		}
		else {
			int pointN = 0;
			if(Q == 5){
				if(!playerIsWhite)
					aGagner = true;
				else
					aPerdu = true;
				return pointN;
			}
			else if((Y == 1 && Z == 1 && Q == 2) ||(Y == 2 && Z == 1 && Q ==1)){
				return countPoints((int)(java.lang.Math.pow(multiplierFactor, Y+Q+1)*0.9), JoueurArtificiel.VALUE_N);
			}
			else if (Q > 5){
				return pointN;
			}
			else if ((Q + Z) > 5){
				// Donne les point pour 0QNB 
				///////////////////////////////////////////////////////////////////
				pointN += countPoints((int)java.lang.Math.pow(multiplierFactor, Q), JoueurArtificiel.VALUE_N);
			}
			else if((Q + Z + Y) == 5 ){
				// Donne les point pour YNZ0QN
				pointN += countPoints((int)java.lang.Math.pow(multiplierFactor, Y+Q) - (int)(java.lang.Math.pow(multiplierFactor, Y+Q)*Z/4), JoueurArtificiel.VALUE_N); // Rajouter facteur espacement Z
			}
			else if((Q + Z + Y) < 5 && (Q + Z + Y + X) >= 5 ){
				// Donne les point pour X0YNZ0QN
				/////////////////////////////////////////////////////////////////
				pointN += countPoints((int)java.lang.Math.pow(multiplierFactor, Y+Q) - (int)(java.lang.Math.pow(multiplierFactor, Y+Q)*Z/4), JoueurArtificiel.VALUE_N); // Rajouter facteur espacement Z
			}
			return pointN;
		}
	}

	private static int X0YBZ0QB(int X, int Y, int Z, int Q, Vector<Byte> vecteur){
		if(vecteur.size() != 0){
			switch (vecteur.remove(0)){
			case JoueurArtificiel.VALUE_B:
				return X0YBZ0QB(X, Y, Z, ++Q, vecteur);
			case JoueurArtificiel.VALUE_N:
				int pointN = 0;
				if(Q == 5){
					if(playerIsWhite)
						aGagner = true;
					else
						aPerdu = true;
					return 0;
				}
				else if (Q > 5){
					pointN += 0;
				}
				else if ((Q + Z) > 5){
					// Donne les point pour 0QNB 
					///////////////////////////////////////////////////////////////////
					pointN += countPoints((int)java.lang.Math.pow(multiplierFactor, Q), JoueurArtificiel.VALUE_B);
				}
				else if((Q + Z + Y) == 5 ){
					// Donne les point pour YNZ0QN
					pointN += countPoints((int)java.lang.Math.pow(multiplierFactor, Y+Q) - (int)(java.lang.Math.pow(multiplierFactor, Y+Q)*Z/4), JoueurArtificiel.VALUE_B); // Rajouter facteur espacement Z
				}
				else if((Q + Z + Y) < 5 && (Q + Z + Y + X) >= 5 ){
					// Donne les point pour X0YNZ0QN
					/////////////////////////////////////////////////////////////////
					pointN += countPoints((int)java.lang.Math.pow(multiplierFactor, Y+Q) - (int)(java.lang.Math.pow(multiplierFactor, Y+Q)*Z/4), JoueurArtificiel.VALUE_B); // Rajouter facteur espacement Z
				}
				else if((Y == 1 && Z == 1 && Q == 2) ||(Y == 2 && Z == 1 && Q ==1)){
					pointN += countPoints((int)(java.lang.Math.pow(multiplierFactor, Y+Q+1)*0.9), JoueurArtificiel.VALUE_B);
				}
				else if(Q==1 && playerIsWhite){
					pointN += countPoints(STICKING_VALUE, JoueurArtificiel.VALUE_B);
				}
				else if(!playerIsWhite && isAlone(vecteur)){
					pointN = countPoints(STICKING_VALUE, JoueurArtificiel.VALUE_N);
				}
				return pointN + XN(1, vecteur);
				
			default : // z�ro JoueurArticiel.VALUE_0
				if(Q == 5){
					if(!playerIsWhite)
						aGagner = true;
					else
						aPerdu = true;
					return 0;
				}
				else if((Y == 1 && Z == 1 && Q == 2) ||(Y == 2 && Z == 1 && Q ==1)){
					return countPoints((int)(java.lang.Math.pow(multiplierFactor, Y+Q+1)*0.9), JoueurArtificiel.VALUE_B) + X0YBZ0(Z,Q,1,vecteur);
				}
				else if (Q > 5){
					return XBY0(Q, 1, vecteur);
				}
				else if ((Q + Z) >= 5){
					// Donne les point pour 0QNB 
					///////////////////////////////////////////////////////////////////
					return X0YBZ0(Z, Q, 1, vecteur) ;
				}
				else if((Q + Z + Y) == 5 ){
					// Donne les point pour YNZ0QN
					////////////////////
					if ( Z != 1)
						return countPoints((int)java.lang.Math.pow(multiplierFactor, Y+Q) - (int)(java.lang.Math.pow(multiplierFactor, Y+Q)*Z/4), JoueurArtificiel.VALUE_B) + X0YBZ0(Z-1, Q, 1, vecteur); // Rajouter facteur espacement Z
					else
						return countPoints((int)java.lang.Math.pow(multiplierFactor, Y+Q) - (int)(java.lang.Math.pow(multiplierFactor, Y+Q)*Z/4), JoueurArtificiel.VALUE_B) + XBY0(Q, 1, vecteur); // Rajouter facteur espacement Z
				}
				else if((Q + Z + Y) < 5 && (Q + Z + Y + X) >= 4 ){ // ERREUR VOLONTAIRE
					// Donne les point pour X0YNZ0QN
					/////////////////////////////////////////////////////////////////
					if ( Z != 1)
						return countPoints((int)java.lang.Math.pow(multiplierFactor, Y+Q) - (int)(java.lang.Math.pow(multiplierFactor, Y+Q)*Z/4), JoueurArtificiel.VALUE_B) + X0YBZ0(Z-1, Q, 1, vecteur); // Rajouter facteur espacement Z
					else
						return countPoints((int)java.lang.Math.pow(multiplierFactor, Y+Q) - (int)(java.lang.Math.pow(multiplierFactor, Y+Q)*Z/4), JoueurArtificiel.VALUE_B) + XBY0(Q, 1, vecteur);
				}
				if ( Z != 1)
					return X0YBZ0(Z-1, Q, 1, vecteur); // Rajouter facteur espacement Z
				else
					return XBY0(Q, 1, vecteur);
			}
		}
		else
		{
			int pointN = 0;
			if(Q == 5){
				if(playerIsWhite)
					aGagner = true;
				else
					aPerdu = true;
				return pointN;
			}
			else if((Y == 1 && Z == 1 && Q == 2) ||(Y == 2 && Z == 1 && Q ==1)){
				return countPoints((int)(java.lang.Math.pow(multiplierFactor, Y+Q+1)*0.9), JoueurArtificiel.VALUE_B);
			}
			else if (Q > 5){
				return pointN;
			}
			else if ((Q + Z) > 5){
				// Donne les point pour 0QNB 
				///////////////////////////////////////////////////////////////////
				pointN += countPoints((int)java.lang.Math.pow(multiplierFactor, Q), JoueurArtificiel.VALUE_B);
			}
			else if((Q + Z + Y) == 5 ){
				// Donne les point pour YNZ0QN
				pointN += countPoints((int)java.lang.Math.pow(multiplierFactor, Y+Q) - (int)(java.lang.Math.pow(multiplierFactor, Y+Q)*Z/4), JoueurArtificiel.VALUE_B); // Rajouter facteur espacement Z
			}
			else if((Q + Z + Y) < 5 && (Q + Z + Y + X) >= 5 ){
				// Donne les point pour X0YNZ0QN
				/////////////////////////////////////////////////////////////////
				pointN += countPoints((int)java.lang.Math.pow(multiplierFactor, Y+Q) - (int)(java.lang.Math.pow(multiplierFactor, Y+Q)*Z/4), JoueurArtificiel.VALUE_B); // Rajouter facteur espacement Z
			}
			return pointN;
		}
	}	
	
	private static int XBY0ZBQ0(int X, int Y, int Z, int Q, Vector<Byte> vecteur){
		if(vecteur.size() != 0){
			switch (vecteur.remove(0)){
			case JoueurArtificiel.VALUE_B:
				if(Y>= 2 && Z >= 3 && Z < 5 && Q > 1){
					return countPoints((int)(java.lang.Math.pow(multiplierFactor, Z+1)*0.9),JoueurArtificiel.VALUE_B)+ X0YB(Q-1, 1, vecteur);
				}
				else if((X+Y+Z+Q)>5){
					////////////////////////////////////////////////////////////////
					if(Y>1){
						return countPoints((int)java.lang.Math.pow(multiplierFactor, X+Z) - (int)(java.lang.Math.pow(multiplierFactor, X+Z)*Y/4), JoueurArtificiel.VALUE_B) + X0YBZ0QB(Y-1, Z, Q, 1, vecteur);
					}
					else if (Q > 1){
						return countPoints((int)java.lang.Math.pow(multiplierFactor, X+Z) - (int)(java.lang.Math.pow(multiplierFactor, X+Z)*Y/4), JoueurArtificiel.VALUE_B) + X0YB(Q-1, 1, vecteur);
					}
					return countPoints((int)java.lang.Math.pow(multiplierFactor, X+Z) - (int)(java.lang.Math.pow(multiplierFactor, X+Z)*Y/4), JoueurArtificiel.VALUE_B) + XN(1, vecteur);
				}
				else if ((X+Y+Z+Q)==5){
					////////////////////////////////////////////////////////////////
					if(Y>1){
						return X0YBZ0QB(Y-1, Z, Q, 1, vecteur);
					}
					else if (Q > 1){
						return X0YB(Q-1, 1, vecteur);
					}
					return XN(1, vecteur);
				}
				else if ((X+Y+Z+Q) == 4){
					if(vecteur.size()!= 0){
						if(vecteur.elementAt(0) == JoueurArtificiel.VALUE_B){
							///////// Point pour B0B0BB ///////////////////////////////////////
							return XBY0ZB(Z, Q, 1, vecteur);
						}
						else if(vecteur.elementAt(0) == JoueurArtificiel.VALUE_N){
							///////// Point pour B0B0BX ///////////////////////////////////////
							return countPoints(90, JoueurArtificiel.VALUE_B) + XB(1, vecteur);
						}
						else{ /// Cas JoueurArtificiel.VALUE_0
							return countPoints(90, JoueurArtificiel.VALUE_B) + XBY0ZB(1, 1, 1 , vecteur);
						}
					}
					else{
						return countPoints(90, JoueurArtificiel.VALUE_B);
					}
				}
			case JoueurArtificiel.VALUE_N:
				if( (X == 2 && Y == 1 && Z == 1)||(X == 1 && Y == 1 && Z == 2)){
					return countPoints((int)(java.lang.Math.pow(multiplierFactor, Z+X+1)*0.9),JoueurArtificiel.VALUE_B)+ X0YN(Q, 1, vecteur);
				}
				else if(Y>= 2 && Z >= 3 && Z < 5 ){
					return countPoints((int)(java.lang.Math.pow(multiplierFactor, Z+1)*0.9),JoueurArtificiel.VALUE_B)+ X0YN(Q, 1, vecteur);
				}
				else if(X+Y+Z <= 5 && (X+Y+Z+Q)>=5){ // Devrait pas avoir a valider X+Y+Z <= 5 
					/////////////////////////////////////////////////////////////////
					return countPoints((int)java.lang.Math.pow(multiplierFactor, X+Z) - (int)(java.lang.Math.pow(multiplierFactor, X+Z)*Y/4), JoueurArtificiel.VALUE_B) + XN(1, vecteur);
				}
				return XN(1, vecteur);
			default : // z�ro JoueurArticiel.VALUE_0
				return XBY0ZBQ0(X, Y, Z, ++Q, vecteur);
			}
		}
		else{
			if( (X == 2 && Y == 1 && Z == 1)||(X == 1 && Y == 1 && Z == 2)){
				return countPoints((int)(java.lang.Math.pow(multiplierFactor, Z+X+1)*0.9),JoueurArtificiel.VALUE_B);
			}
			if(X+Y+Z <= 5 && (X+Y+Z+Q)>=5){ // Devrait pas avoir a valider X+Y+Z <= 5 
				/////////////////////////////////////////////////////////////////
				return countPoints((int)java.lang.Math.pow(multiplierFactor, X+Z) - (int)(java.lang.Math.pow(multiplierFactor, X+Z)*Y/4), JoueurArtificiel.VALUE_B);
			}
			return 0;
		}
	}	
	
	private static int XNY0ZNQ0(int X, int Y, int Z, int Q, Vector<Byte> vecteur){ 
		if(vecteur.size() != 0){
			switch (vecteur.remove(0)){
			case JoueurArtificiel.VALUE_N:
				if(Y>= 2 && Z >= 3 && Z < 5 && Q > 1){
					return countPoints((int)(java.lang.Math.pow(multiplierFactor, Z+1)*0.9),JoueurArtificiel.VALUE_N)+ X0YN(Q-1, 1, vecteur);
				}
				else if((X+Y+Z+Q)>5){
					////////////////////////////////////////////////////////////////
					if(Y>1){
						return countPoints((int)java.lang.Math.pow(multiplierFactor, X+Z) - (int)(java.lang.Math.pow(multiplierFactor, X+Z)*Y/4), JoueurArtificiel.VALUE_N) + X0YNZ0QN(Y-1, Z, Q, 1, vecteur);
					}
					else if (Q > 1){
						return countPoints((int)java.lang.Math.pow(multiplierFactor, X+Z) - (int)(java.lang.Math.pow(multiplierFactor, X+Z)*Y/4), JoueurArtificiel.VALUE_N) + X0YN(Q-1, 1, vecteur);
					}
					return countPoints((int)java.lang.Math.pow(multiplierFactor, X+Z) - (int)(java.lang.Math.pow(multiplierFactor, X+Z)*Y/4), JoueurArtificiel.VALUE_N) + XN(1, vecteur);
				}
				else if ((X+Y+Z+Q)==5){
					////////////////////////////////////////////////////////////////
					if(Y>1){
						return X0YNZ0QN(Y-1, Z, Q, 1, vecteur);
					}
					else if (Q > 1){
						return X0YN(Q-1, 1, vecteur);
					}
					return XN(1, vecteur);
				}
				else if ((X+Y+Z+Q) == 4){
					if(vecteur.size()!= 0){
						if(vecteur.elementAt(0) == JoueurArtificiel.VALUE_N){
							///////// Point pour B0B0BB ///////////////////////////////////////
							return XNY0ZN(Z, Q, 1, vecteur);
						}
						else if(vecteur.elementAt(0) == JoueurArtificiel.VALUE_B){
							///////// Point pour B0B0BX ///////////////////////////////////////
							return countPoints(90, JoueurArtificiel.VALUE_N) + XN(1, vecteur);
						}
						else{ /// Cas JoueurArtificiel.VALUE_0
							return countPoints(90, JoueurArtificiel.VALUE_N) + XNY0ZN(1, 1, 1 , vecteur);
						}
					}
					else{
						return countPoints(90, JoueurArtificiel.VALUE_N);
					}
				}
			case JoueurArtificiel.VALUE_B:
				if( (X == 2 && Y == 1 && Z == 1)||(X == 1 && Y == 1 && Z == 2)){
					return countPoints((int)(java.lang.Math.pow(multiplierFactor, Z+X+1)*0.9),JoueurArtificiel.VALUE_N)+ X0YB(Q, 1, vecteur);
				}
				else if(Y>= 2 && Z >= 3 && Z < 5 ){
					return countPoints((int)(java.lang.Math.pow(multiplierFactor, Z+1)*0.9),JoueurArtificiel.VALUE_N)+ X0YB(Q, 1, vecteur);
				}
				else if(X+Y+Z <= 5 && (X+Y+Z+Q)>=5){ // Devrait pas avoir a valider X+Y+Z <= 5 
					/////////////////////////////////////////////////////////////////
					return countPoints((int)java.lang.Math.pow(multiplierFactor, X+Z)  - (int)(java.lang.Math.pow(multiplierFactor, X+Z)*Y/4), JoueurArtificiel.VALUE_N) + XB(1, vecteur);
				}
				return XN(1, vecteur);
			default : // z�ro JoueurArticiel.VALUE_0
				return XNY0ZNQ0(X, Y, Z, ++Q, vecteur);
			}
		}
		else{
			if( (X == 2 && Y == 1 && Z == 1)||(X == 1 && Y == 1 && Z == 2)){
				return countPoints((int)(java.lang.Math.pow(multiplierFactor, Z+X+1)*0.9),JoueurArtificiel.VALUE_N);
			}
			if((X+Y+Z+Q)>=5){ // Devrait pas avoir a valider X+Y+Z <= 5 
				/////////////////////////////////////////////////////////////////
				return countPoints((int)java.lang.Math.pow(multiplierFactor, X+Z) - (int)(java.lang.Math.pow(multiplierFactor, X+Z)*Y/4), JoueurArtificiel.VALUE_N);
			}
			return 0;
		}
	}	
	
	private static int countPoints(int value, byte playerInCounts){
		if((playerInCounts == JoueurArtificiel.VALUE_B && playerIsWhite)
				|| (playerInCounts == JoueurArtificiel.VALUE_N && !playerIsWhite))
		{
			return (int) (value*0.7); // Victorie avec + 0.7 & - 1.4
		}
		return (int)(-value * 1.4);
	}
	
	private static void DEBUG_LN(String text){
		if(DEBUG_MODE_ACTIVATED){
			System.out.println(text);
		}
	}
	private static void DEBUG(String text){
		if(DEBUG_MODE_ACTIVATED){
			System.out.print(text);
		}
	}
	
	private static boolean isAlone(Vector<Byte> vecteur){
		if(vecteur.size() != 0){
			if(vecteur.elementAt(0) == JoueurArtificiel.VALUE_0)
				return true;
		}
		return false;
	}
}
